#include "head.h"
// 航班信息数据相关操作函数声明

// 数据操作
void flight_data_file_print(f_list *list) //  向文件写入航班信息
{
    //安全判断
    is_empty_double_link_list(list);
    //打开文件
    FILE *fp = fopen(FLIGHTS_FILE, "w+");
    //安全判断
    if (NULL == fp)
    {
        ERRLOG("文件打开失败");
        return;
    }
    //移动光标到开头
    fseek(fp, 0, SEEK_SET);
    //遍历写入
    f_node *ptr = list->next;
    do
    {
        // fprintf(fp, "%d\t%s\t%s\t%s\t%d:%d\t%d:%d\t%s\t%d\t%d\t%d\t%c\n",
        //         ptr->data.id, ptr->data.flighttype, ptr->data.startcity, ptr->data.arrivecity, ptr->data.starttime[0], ptr->data.starttime[1],
        //         ptr->data.arrivetime[0], ptr->data.arrivetime[1], ptr->data.flytime, ptr->data.value, ptr->data.maxNUM, ptr->data.leftbuyersa, ptr->data.whetherfly);
        fprintf(fp, "%d\t\t", ptr->data.id);
        fprintf(fp, "%s\t\t", ptr->data.flighttype);
        fprintf(fp, "%s\t", ptr->data.startcity);
        fprintf(fp, "%s\t", ptr->data.arrivecity);
        fprintf(fp, "%d:%d\t\t", ptr->data.starttime[0], ptr->data.starttime[1]);
        fprintf(fp, "%d:%d\t\t", ptr->data.arrivetime[0], ptr->data.arrivetime[1]);
        fprintf(fp, "%s\t\t", ptr->data.flytime);
        fprintf(fp, "%d\t\t", ptr->data.value);
        fprintf(fp, "%d\t\t", ptr->data.maxNUM);
        fprintf(fp, "%d\t\t", ptr->data.leftbuyersa);
        fprintf(fp, "%c\n", ptr->data.whetherfly);
        ptr = ptr->next;
    } while (ptr != list->next);

    fflush(fp); // 刷新文件
    fclose(fp);
}

void flight_data_file_scanf(f_list *list) //  向文件读取航班信息
{
    // 安全判断
    if (NULL == list)
    {
        ERRLOG("双向循环链表 为 NULL");
        return;
    }

    FILE *fp = fopen(FLIGHTS_FILE, "r");
    if (NULL == fp)
    {
        ERRLOG("文件打开失败!");
        return;
    }
    // 移动光标
    fseek(fp, 0, SEEK_SET);
    // 清空链表
    // if (NULL!=list->next)
    // {
    //     clear_double_link_list(list);
    // }
    f_data data;
    int line_num = 0;

    // 检测文件行数
    // line_num = count_line(FLIGHTS_FILE);
    char ch = 0;
    while (EOF != (ch = fgetc(fp)))
    {
        if ('\n' == ch)
        {
            line_num++;
            printf("line_num=%d\n", line_num);
        }
    }

    fflush(fp); // 刷新文件

    // 移动光标到开头
    fseek(fp, 0, SEEK_SET);
    printf("%d\n",line_num);

    for (int i = 0; i < line_num; i++)
    {
        fscanf(fp, "%d\t\t", &data.id);
        fscanf(fp, "%s\t\t", data.flighttype);
        fscanf(fp, "%s\t", data.startcity);
        fscanf(fp, "%s\t", data.arrivecity);
        fscanf(fp, "%d:%d\t\t", &data.starttime[0], &data.starttime[1]);
        fscanf(fp, "%d:%d\t\t", &data.arrivetime[0], &data.arrivetime[1]);
        fscanf(fp, "%s\t\t", data.flytime);
        fscanf(fp, "%d\t\t", &data.value);
        fscanf(fp, "%d\t\t", &data.maxNUM);
        fscanf(fp, "%d\t\t", &data.leftbuyersa);
        fscanf(fp, "%c\n", &data.whetherfly);
        insert_node_normal(list, data, i + 1); // 插入到链表
    }
    //写入到文件
    flight_data_file_print(list);
    fflush(fp); // 刷新文件
    fclose(fp);
    return;
}

//按航班班次排序,只改内容,不改指针
void time_sort(f_list *list)
{
   //临时航班信息结构体变量(用于临时交换)
   f_data temp_data;
   //记录头结点的位置
   f_node *head = list->next;
   f_node *p1 ,*p2;
   int len = count_line(FLIGHTS_FILE);//计算文件行数
   for (int i = 1; i < len ; i++)
   {
    //    每次循环一趟后，重新从头开始比较
        p1 = head;
        p2 = p1->next;
       for (int j = 1; j < len - i; j++)
       {
           if (p1->data.id > p2->data.id)
           {
               temp_data = p1->data;
               p1->data = p2->data;
               p2->data = temp_data;
            //    flag = 1;
           }
           // 继续往下比较
           p1 = p2;
           p2 = p2->next;
       }
    }
    view_flight_info(list,0.5); // 打印排序后的结果
    return;
}

//按价格排序
void price_sort(f_list *list)
{
    // 临时航班信息结构体变量(用于临时交换)
    f_data temp_data;
    int len = count_line(FLIGHTS_FILE); // 计算文件行数
    //记录头结点的位置
    f_node *head = list->next;
    f_node *p1,*p2;
    for (int i = 1; i < len ; i++)
    {
        //    每次循环一趟后，重新从头开始比较
        p1 = head;
        p2 = p1->next;
        // int flag = 0; // 是否交换标识符
        for (int j = 1; j < len -i; j++)
        {
            if (p1->data.value > p2->data.value)
            {
                temp_data = p1->data;
                p1->data = p2->data;
                p2->data = temp_data;
                // flag = 1;
            }
            // 继续往下比较
            p1 = p2;
            p2 = p2->next;
        }
        // if (flag == 0)
        // {
        //     print_forward_double_link_list(list);//打印排序后的结果
        //     return;
        // }   
    }
    view_flight_info(list,0.5); // 打印排序后的结果
    return;
}

// 查看航班信息
void view_flight_info(f_list *list,int sleep_num)
{
    //打印所有航班信息
    print_forward_double_link_list(list, sleep_num);
    //选择排序方式
    puts("");
    // 排序选择
    int select = 0;
    text_center("1——按航班班次排序\n", GREEN);
    text_center("2——按机票价格排序\n", GREEN);
    text_center("3——不需要排序继续\n", GREEN);
    puts("");
    text_center("请选择你的排序方式:", GREEN);
    scanf(" %d", &select);
    if (1 == select)
    {
        time_sort(list); // 按班次升序
        return;
    }
    else if (2 == select)
    {
        price_sort(list); // 按价格升序
        return;
    }

    puts("");
    text_center("如若预定机票,请返回菜单界面进行操作!\n", YELLOW);
    char ch = ' ';
    while (10 != ch)
    {
        sleep(1); // 当前进程进入休眠态 S
        ch = getchar();
    }
    return;
}

// 生成随机航班信息
void random_flight_info(f_list *list,int num)
{
    // 初始化随机数生成器
    srand(time(NULL)); 
    f_data flight;
    // 假设的飞机机型数组
    char *flighttypes[] = {"Boeing", "Airbus", "Boeing", "Airbus", "C919", "E170", "E190"};
    // 假设的城市数组
    char *cities[] = {"北京", "上海", "广州", "深圳", "武汉",
                      "成都", "西安", "杭州", "重庆", "南京",
                      "青岛", "大连", "厦门", "沈阳", "天津",
                      "长沙", "昆明", "郑州", "哈尔滨", "济南",
                      "长春", "贵阳", "海口", "兰州",
                      "太原", "合肥", "石家庄", "南宁", "福州",
                      "南昌", "银川", "西宁", "温州",
                      "宁波", "无锡", "苏州", "常州", "泉州", "烟台",
                      "三亚", "珠海", "桂林", "张家界", "丽江", "大连",
                      "台北", "高雄", "新加坡", "吉隆坡", "曼谷", "首尔",
                      "东京", "大阪", "悉尼", "墨尔本", "奥克兰",
                      "伦敦", "巴黎", "柏林", "罗马","马德里", "莫斯科"};

    // 计算城市数组大小
    int city_name_size = sizeof(cities) / sizeof(cities[0]);
    // 计算机型数组大小
    int flight_type_size = sizeof(flighttypes) / sizeof(flighttypes[0]);

    for (int i = num; i > 0; i--)
    {
        // 生成航班ID
        flight.id = i;
        // 随机选择飞机机型
        strcpy(flight.flighttype, flighttypes[rand() % flight_type_size]);

        // 随机选择起点和终点城市
        strcpy(flight.startcity, cities[rand() % city_name_size]);
        strcpy(flight.arrivecity, cities[rand() % city_name_size]);

        // 随机生成起飞和到达时间（假设为24小时制）
        flight.starttime[0] = rand() % 24; // 起飞小时
        flight.starttime[1] = rand() % 60; // 起飞分钟

        // 假设飞行时间至少为10分钟，最多为12小时（您可以根据需要调整这些值）
        int flyMinutesMin = 10;
        int flyMinutesMax = 12 * 60; // 转换为分钟以便计算
        int flyMinutes = rand() % (flyMinutesMax - flyMinutesMin + 1) + flyMinutesMin;

        // 将飞行时间转换为小时和分钟
        int flyHours = flyMinutes / 60;
        int flyRemainderMinutes = flyMinutes % 60;

        // 计算到达时间（注意：这里我们简化了逻辑，没有考虑日期变更）
        flight.arrivetime[0] = (flight.starttime[0] + flyHours) % 24;
        int totalMinutes = flight.starttime[1] + flyRemainderMinutes;
        if (totalMinutes >= 60)
        {
            flight.arrivetime[1] = totalMinutes % 60;
            if (flight.arrivetime[0] == 23 && totalMinutes >= 60)
            {
                // 处理跨天情况（如果需要的话，但在这个简单的24小时制内我们不考虑跨天）
                // 注意：在这个简单的例子中，我们假设不跨天，所以上面的代码已经足够
            }
        }
        else
        {
            flight.arrivetime[1] = totalMinutes;
        }

        // 格式化飞行时间到 flytime 字符串
        sprintf(flight.flytime, "%dh%02dm", flyHours, flyRemainderMinutes);

        // 随机生成票价
        flight.value = rand() % 500 + 500; // 假设票价在500到1000之间

        // 随机生成额定载客量
        flight.maxNUM = rand() % 100 + 100; // 假设额定载客量在100到200之间

        // 随机生成剩余座位数量
        flight.leftbuyersa = rand() % flight.maxNUM;

        // 随机选择是否起飞
        flight.whetherfly = rand() % 2 ? 'y' : 'n';

        //头插保存到文件中
        insert_double_node(list, flight, 1);
    }
    return;
}
